home *** CD-ROM | disk | FTP | other *** search
/ Adobe Graphics & Publishing SDK 1996 December / Adobe Graphics & Publishing SDK 1996 December.iso / mac / After Effects 3.1 SDK Mac / Examples / Effects Samples / Resizer / Resizer.c < prev   
Text File  |  1996-11-06  |  9KB  |  326 lines

  1. /**
  2.     Resizer.c
  3.     
  4.     Part of the Adobe After Effects 3.1 SDK.
  5.     (c) 1994-96, Adobe Systems Inc, All Rights Reserved.
  6.     
  7.     This effect draws a border of user-specified color and width around
  8.     the edges of a layer, resizing the output in the process.
  9.     
  10.     The effect also provides a checkbox to turn on and off the code that
  11.     compensates for the downsample factor.
  12.     
  13.     This demonstrates:
  14.         Using a Slider control.
  15.         Using a Color control.
  16.         Using a Checkbox control.
  17.         Using the PF_COPY callback routine.
  18.         Using the PF_FILL callback routine.
  19.         Writing an effect whose output is larger than its input.
  20.         Honoring the downsample factors to create correct output at
  21.             decreased resolution.
  22.         
  23.     Revision History
  24.         1.0, created by dmw, 14 Jan 94
  25.         1.1, updated for Mac/Power Mac, dmw, 13 Oct 94        
  26.         2.0, updated for AE 3.0, dmw
  27.         2.1, Added call to AEFX_CLR_STRUCT macro to clear out PF_ParamDef, ba, 6 Nov 96
  28. **/
  29.  
  30. #include "AE_EffectCB.h"
  31. #include "AE_Macros.h"
  32. #include <A4Stuff.h>
  33.  
  34. /**
  35.  ** Here we #define our version values for use in the PF_VERSION
  36.  ** macro. After Effects uses these values to determine which
  37.  ** plug-in to run if it finds multiple version of the same effect
  38.  ** on the user's drive.
  39.  **
  40.  **/
  41.  
  42. #define    MAJOR_VERSION    2
  43. #define    MINOR_VERSION    0
  44. #define    BUG_VERSION        0
  45. #define    STAGE_VERSION    PF_Stage_RELEASE
  46. #define    BUILD_VERSION    0
  47.  
  48.  
  49. /**
  50.  ** Some more useful #define's
  51.  **
  52.  **/
  53.  
  54. #define        NAME            "Resizer"
  55. #define        DESCRIPTION        "Demonstrate Output Buffer Resizing"
  56.  
  57.  
  58. /** Parameter Definition Constants
  59.  
  60.     Here we define the parameters, their default
  61.     settings, and minimum and maximum values.
  62.  
  63. **/
  64.  
  65. enum {
  66.     RESIZE_INPUT = 0,
  67.     RESIZE_AMOUNT,
  68.     RESIZE_COLOR,
  69.     RESIZE_DOWNSAMPLE,
  70.     
  71.     RESIZE_NUM_PARAMS
  72. };
  73.  
  74. #define    RESIZE_AMOUNT_MIN        0
  75. #define    RESIZE_AMOUNT_MAX        100;
  76. #define    RESIZE_AMOUNT_DFLT        0;
  77.  
  78.  
  79. /** Command Specific Subroutines
  80.  
  81.     This plug-in only deals with the commands:
  82.         PF_Cmd_ABOUT
  83.         PF_Cmd_GLOBAL_SETUP
  84.         PF_Cmd_PARAMS_SETUP
  85.         PF_Cmd_FRAME_SETUP
  86.         PF_Cmd_RENDER
  87.     All other commands are ignored.  There is a routine for
  88.     each command, and a main routine to dispatch at the bottom.
  89.  
  90.     There is no PF_Cmd_GLOBAL_SETDOWN because I don't allocate
  91.     any memory in GLOBAL_SETUP, so I don't have any cleanup to do.
  92.     
  93. **/
  94.  
  95. static PF_Err About (
  96.     PF_InData        *in_data,
  97.     PF_OutData        *out_data,
  98.     PF_ParamDef        *params[],
  99.     PF_LayerDef        *output )
  100. {
  101.     PF_SPRINTF(out_data->return_msg,
  102.         "%s, v%d.%d\r%s",
  103.         NAME, MAJOR_VERSION, MINOR_VERSION, DESCRIPTION);
  104.  
  105.     return PF_Err_NONE;
  106. }
  107.  
  108.  
  109. static PF_Err GlobalSetup (
  110.     PF_InData        *in_data,
  111.     PF_OutData        *out_data,
  112.     PF_ParamDef        *params[],
  113.     PF_LayerDef        *output )
  114. {
  115.     PF_Err err = PF_Err_NONE;
  116.     
  117.     /* Need to let AE know what version of the "Resizer" plug-in
  118.      * we are.
  119.      */
  120.     out_data->my_version = PF_VERSION(MAJOR_VERSION, MINOR_VERSION,
  121.                                       BUG_VERSION, STAGE_VERSION, BUILD_VERSION);
  122.  
  123.     /* This effect resizes its output buffer to be larger, so we should let
  124.      * After Effects know that.
  125.      */
  126.      
  127.     out_data->out_flags |= PF_OutFlag_I_EXPAND_BUFFER;
  128.     
  129.     return err;
  130. }
  131.  
  132.  
  133. static PF_Err ParamsSetup (
  134.     PF_InData        *in_data,
  135.     PF_OutData        *out_data,
  136.     PF_ParamDef        *params[],
  137.     PF_LayerDef        *output )
  138. {
  139.     PF_Err            err = PF_Err_NONE;
  140.     PF_ParamDef        def;                /* scratch space for a parameter definition */
  141.     PF_Pixel        white = {255, 255, 255, 255};
  142.     char            *checkbox_string = "Correct At All Resolutions";
  143.     
  144.     /* Always clear out the PF_ParamDef structure before adding your parameters,
  145.      * this macro will do that. */
  146.     
  147.     AEFX_CLR_STRUCT(def);
  148.     
  149.     /* Create the SLIDER parameter... */
  150.  
  151.     def.param_type = PF_Param_SLIDER;
  152.     PF_STRCPY(def.name, "Resize Amount (pixels)");
  153.     def.flags = def.ui_flags = def.ui_width = def.ui_height = 0;    /* clear these to avoid trouble */
  154.     def.u.sd.value_str[0] = '\0';                                    /* set these to be empty to avoid garbage strings */
  155.     def.u.sd.value_desc[0] = '\0';
  156.     
  157.     /* The min and max values of the slider and the min and max
  158.      * values the user can type will be the same value... */
  159.  
  160.     def.u.sd.valid_min = def.u.sd.slider_min = RESIZE_AMOUNT_MIN;
  161.     def.u.sd.valid_max = def.u.sd.slider_max = RESIZE_AMOUNT_MAX;
  162.     def.u.sd.value = def.u.sd.dephault = RESIZE_AMOUNT_DFLT;
  163.     if (err = PF_ADD_PARAM(in_data, -1, &def)) return err;
  164.  
  165.     /* Create the COLOR parameter... */
  166.  
  167.     AEFX_CLR_STRUCT(def);
  168.     def.param_type = PF_Param_COLOR;
  169.     def.flags = 0;
  170.     PF_STRCPY(def.name, "Resized Area Color");
  171.     def.u.cd.dephault = def.u.cd.value = white;
  172.     if (err = PF_ADD_PARAM(in_data, -1, &def)) return err;
  173.  
  174.     /* Create the CHECKBOX parameter... */
  175.  
  176.     AEFX_CLR_STRUCT(def);
  177.     def.param_type = PF_Param_CHECKBOX;
  178.     def.flags = 0;
  179.     PF_STRCPY(def.name, "Use Downsample Factors");
  180.     def.u.bd.value = def.u.bd.dephault = FALSE;
  181.     def.u.bd.u.nameptr = checkbox_string;                /* this is strictly a pointer; don't
  182.                                                          * STRCPY into it! */
  183.     if (err = PF_ADD_PARAM(in_data, -1, &def)) return err;
  184.     
  185.     out_data->num_params = RESIZE_NUM_PARAMS;
  186.     
  187.     return err;
  188. }
  189.  
  190.  
  191. static PF_Err FrameSetup (
  192.     PF_InData        *in_data,
  193.     PF_OutData        *out_data,
  194.     PF_ParamDef        *params[],
  195.     PF_LayerDef        *output )
  196. {
  197.     long            border = params[RESIZE_AMOUNT]->u.sd.value;
  198.     long            border_x, border_y;
  199.     
  200.     if (params[RESIZE_DOWNSAMPLE]->u.bd.value) {
  201.         
  202.         /* Need to shrink the border to accomodate decreased resolutions! You
  203.          * should do this with any pixel-valued parameter.
  204.          *
  205.          * Note that we're looking at the value of the DOWNSAMPLE checkbox parameter
  206.          * to decide whether or not to honor downsample sample. You should always do this...
  207.          * the checkbox is provided for illustration purposes.
  208.          */
  209.     
  210.         border_x = border * (in_data->downsample_x.num/(double)in_data->downsample_x.den);
  211.         border_y = border * (in_data->downsample_y.num/(double)in_data->downsample_y.den);
  212.  
  213.     } else {
  214.         /* Let's see what happens when we don't bother with the downsample factor */
  215.         
  216.         border_x = border_y = border;
  217.     }
  218.     
  219.     /* add 2 times the border width and height to the input width and
  220.      * height to get the final output size. (The border will appear on
  221.      * the left and the right */
  222.      
  223.     out_data->width = 2*border_x + params[0]->u.ld.width;
  224.     out_data->height = 2*border_y + params[0]->u.ld.height;
  225.     
  226.     /* Tell After Effects that the origin of the input buffer corresponds to
  227.      * the (border_x, border_y) pixel in the output buffer. This effectively
  228.      * shifts the output layer up and to the left by (border_x, border_y)
  229.      */
  230.      
  231.     out_data->origin.h = border_x;
  232.     out_data->origin.v = border_y;
  233.  
  234.     return PF_Err_NONE;
  235. }
  236.  
  237.  
  238. static PF_Err Render (
  239.     PF_InData        *in_data,
  240.     PF_OutData        *out_data,
  241.     PF_ParamDef        *params[],
  242.     PF_LayerDef        *output )
  243. {
  244.     PF_Err err = PF_Err_NONE;
  245.  
  246.     PF_Pixel    color;
  247.     Rect        dst_r;
  248.     long        border = params[RESIZE_AMOUNT]->u.sd.value;
  249.     long        border_x, border_y;
  250.     
  251.     if (params[RESIZE_DOWNSAMPLE]->u.bd.value) {
  252.     
  253.         /* Need to shrink the border to accomodate decreased resolutions! You
  254.          * should do this with any pixel-valued parameter.
  255.          *
  256.          * Note that we're looking at the value of the DOWNSAMPLE checkbox parameter
  257.          * to decide whether or not to honor downsample sample. You should always do this...
  258.          * the checkbox is provided for illustration purposes.
  259.          */
  260.          
  261.         border_x = border * (in_data->downsample_x.num/(double)in_data->downsample_x.den);
  262.         border_y = border * (in_data->downsample_y.num/(double)in_data->downsample_y.den);
  263.  
  264.     } else {
  265.         /* Let's see what happens when we don't bother with the downsample factor */
  266.         border_x = border_y = border;
  267.     }
  268.     
  269.     /* get the color parameter */
  270.     color = params[RESIZE_COLOR]->u.cd.value;
  271.     
  272.     /* first fill the entire output buffer with the chosen color */    
  273.     err = PF_FILL(&color, NULL, output);
  274.     
  275.     if (!err) {
  276.         /* set up the destination rectangle to be centered in the output buffer. */
  277.         
  278.         dst_r.left = border_x;
  279.         dst_r.top = border_y;
  280.         dst_r.right = dst_r.left + params[0]->u.ld.width;
  281.         dst_r.bottom = dst_r.top + params[0]->u.ld.height;
  282.  
  283.         /* now copy the entire input layer (pass NULL as the rect for the whole
  284.          * layer) to the dst_r rectangle in the output buffer.
  285.          */
  286.         err = PF_COPY(¶ms[RESIZE_INPUT]->u.ld, output, NULL, &dst_r);
  287.     }
  288.  
  289.     return err;
  290. }
  291.  
  292.  
  293. PF_Err main (
  294.     PF_Cmd            cmd,
  295.     PF_InData        *in_data,
  296.     PF_OutData        *out_data,
  297.     PF_ParamDef        *params[],
  298.     PF_LayerDef        *output )
  299. {
  300.     PF_Err        err = PF_Err_NONE;
  301.     
  302.     EnterCodeResource();        /* this only works in Metrowerks */
  303.     
  304.     switch (cmd) {
  305.         case PF_Cmd_ABOUT:
  306.             err = About(in_data,out_data,params,output);
  307.             break;
  308.         case PF_Cmd_GLOBAL_SETUP:
  309.             err = GlobalSetup(in_data,out_data,params,output);
  310.             break;
  311.         case PF_Cmd_PARAMS_SETUP:
  312.             err = ParamsSetup(in_data,out_data,params,output);
  313.             break;
  314.         case PF_Cmd_FRAME_SETUP:
  315.             err = FrameSetup(in_data,out_data,params,output);
  316.             break;
  317.         case PF_Cmd_RENDER:
  318.             err = Render(in_data,out_data,params,output);
  319.             break;
  320.     }
  321.     
  322.     ExitCodeResource();
  323.     
  324.     return err;
  325. }
  326.